package sxr.common.aspect;

import cn.thinkjoy.springboot.vuc.common.annotation.LogValue;
import com.alibaba.fastjson.JSONObject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * Created by xufei on 2019/3/15.
 */
@Aspect
@Component
public class LogAspect {
    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Pointcut("@annotation(cn.thinkjoy.springboot.vuc.common.annotation.LogValue)")
    public void logPointCut(){
    }

//    @Before("logPointCut()")
//    public void doBefore(JoinPoint joinPoint) throws Throwable {
//        // 接收到请求，记录请求内容
//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = attributes.getRequest();
//
//        // 记录下请求内容
//        logger.info("请求地址：" + request.getRequestURL().toString());
//        logger.info("HTTP METHOD：" + request.getMethod());
//        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//        logger.info("CLASS_METHOD：" + signature.getDeclaringTypeName() + "." + signature.getName());
//        String[] parameterNames = signature.getParameterNames();
//        logger.info("参数名："+ Arrays.toString(parameterNames));
//        logger.info("参数值：" + Arrays.toString(joinPoint.getArgs()));
//
//    }

    @Around("logPointCut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object ob = pjp.proceed();// ob 为方法的返回值
        logger.info("耗时 : " + (System.currentTimeMillis() - startTime));
        return ob;
    }

    @AfterReturning(returning = "retVal", pointcut = "logPointCut()")// returning的值和doAfterReturning的参数名一致
    public void doAfterReturning(JoinPoint joinPoint,Object retVal) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //类名，方法名
        String  className=joinPoint.getTarget().getClass().getName();
        String  methodName=signature.getName();
        logger.info("调用方法："+className+"."+methodName);
        //请求参数
        Object[] args = joinPoint.getArgs();

        Method method = signature.getMethod();
        LogValue logValue = method.getAnnotation(LogValue.class);
        logger.info("业务类型:"+logValue.bizType()+",操作类型："+logValue.operType()+",操作说明："+logValue.desc());
        logger.info("参数:"+JSONObject.toJSONString(args));
        // 处理完请求，返回内容(返回值太复杂时，打印的是物理存储空间的地址)
        logger.info("返回值:" + JSONObject.toJSONString(retVal));

    }
}
